#ifndef __COMMON_H
#define __COMMON_H
#include "stm32f10x.h"

extern volatile uint32_t TimeoutCnt;

enum _generic_result
{
	kResult_Success = 0,
	kResult_Fail,
	kResult_ReadOnly,
	kResult_OutOfRange,
	kResult_InvalidArgument,
	kResult_Timeout,
	kResult_NoTransferInProgress,
	kResult_Warning,
	kResult_Error,
	kResult_AbortDataPhase,
	kResult_Ping,
};


#ifndef  _false
	#define  _false	0
#endif

#ifndef  _true
	#define  _true	1
#endif

#ifndef NULL
	#define NULL 	 (void *)0
#endif

#ifndef _INLINE_
	#define _INLINE_ __inline
#endif

#ifndef PNULL
	#define PNULL (void *)0
#endif

#ifndef TRUE
  #define TRUE (bool)(1)
#endif

#ifndef FALSE
  #define FALSE (bool)(0)
#endif

/* Bit defined */
#define BIT0			(0x01)
#define BIT1			(0x02)
#define BIT2			(0x04)
#define BIT3			(0x08)
#define BIT4			(0x10)
#define BIT5			(0x20)
#define BIT6			(0x40)
#define BIT7			(0x80)
#define BIT8			(0x100)
#define BIT9			(0x200)
#define BIT10			(0x400)
#define BIT11			(0x800)
#define BIT12			(0x1000)
#define BIT13			(0x2000)
#define BIT14			(0x4000)
#define BIT15			(0x8000)

/* Bit defined */
#define BIT_0			(0x01)
#define BIT_1			(0x02)
#define BIT_2			(0x04)
#define BIT_3			(0x08)
#define BIT_4			(0x10)
#define BIT_5			(0x20)
#define BIT_6			(0x40)
#define BIT_7			(0x80)

///********************  Task Layer  *******************/
//extern    u8        g_Maintask;        //?????
//extern    u8        ga_Subtask[8];     //?????
//
//#define Var_Fill(var,data)      for(u16 ii = 0; ii < sizeof(var); ++ii)\
//                                *(((u8*)(&var))+ii) = data              //???var???data
//



#ifndef MAX
	#define MAX(a, b)    ((a) > (b) ? (a) : (b))
#endif

#ifndef MIN
	#define MIN(a, b)    ((a) > (b) ? (b) : (a))
#endif

//#define SHIELD_WARNING(a) ((a) = (a))
#define SHIELD_WARNING(a) ((void)(a))

#ifndef SET_BIT
	#define SET_BIT(REG, BIT)     ((REG) |= (BIT))
#endif

#ifndef CLEAR_BIT
	#define CLEAR_BIT(REG, BIT)   ((REG) &= ~(BIT))
#endif

#ifndef READ_BIT
	#define READ_BIT(REG, BIT)    ((REG) & (BIT))
#endif

#ifndef CLEAR_REG
	#define CLEAR_REG(REG)        ((REG) = (0x0))
#endif

#ifndef WRITE_REG
	#define WRITE_REG(REG, VAL)   ((REG) = (VAL))
#endif

#ifndef READ_REG
	#define READ_REG(REG)         ((REG))
#endif


#ifndef ENABLE_IRQ
	#define ENABLE_IRQ()         __enable_irq()
#endif

#ifndef DISABLE_IRQ
	#define DISABLE_IRQ()        __disable_irq()
#endif

#ifndef NOP
	#define NOP()                  __NOP()
#endif

#ifndef SYSTEM_RESET
	#define SYSTEM_RESET()       NVIC_SystemReset()
#endif

#define DIV(a,b) ((a)/(b) - ((a)%(b)<0))

/*
 * \brief   Typecast the macro argument into milliseconds
 */
#define TmrMilliseconds( n )    ( (U32) (n) * 1 )
   
    
/*
 * \brief   Converts the macro argument from seconds to Milliseconds
 */
#define TmrSecondsToMilliseconds( n )   ( (U32) ((n) * 1000) )

/*
 * \brief   Converts the macro argument from microseconds to seconds
 */
#define TmrMicrosecondsToSeconds( n )   ( ((n) + 500000) / 1000000 )

/*
 * \brief   Converts the macro argument (i.e. seconds) into milliseconds
 */
#define TmrSeconds( n )         ( (U32) (TmrMilliseconds(n) * 1000) )

/*
 * \brief   Converts the macro argument (i.e. minutes) into milliseconds
 */
#define TmrMinutes( n )         ( (U32) (TmrSeconds(n) * 60) )

/* Compute the number of elements of an array */
#define NumberOfElements(x)     (sizeof(x)/sizeof((x)[0]))

/* Compute the size of a string initialized with quotation marks */
#define SizeOfString(string)    (sizeof(string) - 1)

#define GetRelAddr(strct, member) ((uint32_t)&(((strct*)(void *)0)->member))
#define GetSizeOfMember(strct, member) sizeof(((strct*)(void *)0)->member)

#define BigtoLittle16(A)              (( ((U16)(A) & 0xff00) >> 8)| (( (U16)(A) & 0x00ff) << 8))  


#define BigtoLittle32(A)              ((( (U32)(A) & 0xff000000) >> 24) | \
                                       (( (U32)(A) & 0x00ff0000) >> 8)   | \
                                       (( (U32)(A) & 0x0000ff00) << 8)   | \
                                       (( (U32)(A) & 0x000000ff) << 24))  

#define UID_BASE              0x1FFFF7E8U    /*!< Unique device ID register base address */

void time_management(void);
uint8_t get_nextStatus(uint8_t flag_true, uint16_t cnt, uint8_t currstatus);
uint8_t get_CEREG(uint8_t flag_true, uint16_t cnt, uint8_t currstatus);
uint8_t crc8_sum(const uint8_t data[], unsigned int length);
uint16_t crc16_sum(uint8_t *ptr, uint16_t len);
uint8_t Check_Data(uint8_t *rbuf,uint8_t len,const uint8_t* head,uint8_t trail);
uint8_t Check_Modbus_Data(uint8_t *rbuf,uint8_t len,const uint8_t* head);
uint8_t *search_buf(const uint8_t* buf,const uint16_t buf_len,const uint8_t* flag,uint16_t flag_len);
uint8_t nm_str2ip(uint8_t *str,uint8_t ip[]);
void FactoryReset(void);
void BubbleSort(int a[], int len);
#endif
